技巧104 限制容器可以运行的内核

默认情况下,Docker可以在机器的任意内核上运行。只有一个进程和线程的容器明显最多只能耗尽一个内核,但是容器中的多线程程序(或多个单线程程序)可以使用 CPU 上所有的内核。如果有一个容器比其他容器都重要,用户可能想对这个行为进行修改——面向客户的应用每次都要在内部日常报告系统运行的时候争抢CPU可不太好。本技巧还可以用于防止失控的容器把用户挡在服务器的SSH之外。

问题

想要让容器有最小CPU分配额,对CPU消耗有硬性的限制,或者想要限制可以运行容器的内核。

解决方案

使用 --cpuset-cpus 选项来为容器保留CPU内核。

在多核计算机上用户需要遵循本技巧以合理探索 --cpuset-cpus 选项。如果使用的是云机器可能遇不到这种情况。

提示

老版本的Docker使用的是现在已经弃用的 --cpuset 标志。如果 --cpuset-cpus 不工作,可以试一下 --cpuset

我们将使用 htop 命令来看一下 --cpuset-cpus 选项的作用,这条命令会给出计算机内核使用的有用图形。请在继续之前确保这个命令已经装好——通常从系统包管理器以 htop 包的形式提供。或者,可以在一个以 --pid=host 选项启动的Ubuntu容器里安装它,这样就可以把宿主机的信息暴露给容器。

如果现在执行 htop ,大概不会看到任何内核处于忙碌状态。在两个不同的终端里执行以下命令,以模拟多个容器内部的负载:

docker run ubuntu:14.04 sh -c 'cat /dev/zero >/dev/null'

现在回头来看 htop ,可以看到有两个内核显示出 100%使用率。为了限制到一个内核上, docker kill 之前的容器,然后在两个终端里执行以下命令:

docker run --cpuset-cpus=0 ubuntu:14.04 sh -c 'cat /dev/zero >/dev/null'

现在 htop 会显示出这些容器只使用了第一个内核。

--cpuset-cpus 选项允许通过逗号分隔的列表( 0, 1, 2 )、范围( 0-2 )或者两者结合的方式( 0-1, 3 )来指定多个内核。因此为宿主机保留CPU就是在给容器选范围的时候排除一个内核的事儿了。

讨论

这个功能可以以多种方式使用。例如,可以通过不断分配剩余CPU给运行中的容器的方式,来为宿主机进程保留特定的CPU;也可以限制特定的容器运行在各自独立的CPU上,从而防止它们干扰其他容器所用的计算。

在多租户环境中,保证工作负载不互相干扰简直令人喜出望外。

results matching ""

    No results matching ""